/**
 * 装饰器、装饰器工厂
 */

import { Animation, Component, Node } from "cc";

/** 快速绑定的组件类型 */
export type TBindComp = typeof Component | typeof Animation;

/** 快速绑定的节点、组件的信息 */
export interface IBindInfo {
    nodeName: string; // 节点名
    isAutoAddComp: boolean; // 对应节点上不存在指定类型的组件时，是否自动添加
    bindType: typeof Node | TBindComp; // 绑定的类型
}

/**
 * 使用快速绑定装饰器的目标数据结构
 * _$bindMap$_: Map<类的属性名, IBindInfo>
 */
export type TQuickBindExt = { _$bindMap$_?: Map<string, IBindInfo>, };

/**
 * 快速绑定节点、组件的装饰器的工厂
 * @param nodeName 节点名
 * @param bindType 绑定的类型
 * @param isAutoAddComp 对应节点上不存在指定类型的组件时，是否自动添加，默认为false。当 buildType 为 Node 时，该值无效。
 * @returns 
 */
export function quickBind(nodeName: string, bindType: typeof Node | TBindComp, isAutoAddComp: boolean = false) {
    /**
     * 快速绑定节点、组件的装饰器。
     * @target 装饰的目标对象，对于静态成员来说是类的构造函数，对于实例成员来说是类的原型对象。
     * @propertyName 装饰的属性名
     */
    return function (target: Object & TQuickBindExt, propertyName: string): void {
        if (!target.hasOwnProperty("_$bindMap$_")) {
            target._$bindMap$_ = new Map<string, IBindInfo>();
        }
        const bindInfo: IBindInfo = {
            nodeName: nodeName,
            isAutoAddComp: isAutoAddComp,
            bindType: bindType,
        };
        target._$bindMap$_!.set(propertyName, bindInfo);
    }
}